package net.cloudsun.tree.util;

import net.cloudsun.tree.binary.BinaryNode;
import net.cloudsun.tree.binary.NodeString;

import java.util.Map;

/**
 * 字符串数组工具类
 *
 * @author Ryan
 * @since 1.2
 */
public class CharArrayUtils {

    private CharArrayUtils() {}

    public static <T> char[][] getCharMatrix(Map<BinaryNode<T>, NodeString<T>> map, int width, int height) {
        char[][] chars = new char[(height << 1) - 1][width];

        // 加入父子连接字符串
        // 0 2 4
        map.forEach((node,nodeString) -> {
            final char[] line = chars[nodeString.getY() << 1];
            final char[] charArray = node.toString().toCharArray();
            // 打印值
            // v是节点坐标+长度
            // 将节点的值往矩阵填写
            for (int i = 0; i < nodeString.getLength(); i++) {
                // v.x + i
                line[nodeString.getX() + i] = charArray[i];
            }
            if (node.getParent() != null) {
                nodeString.addParentLink(chars);
            }
        });
        return chars;
    }

    /**
     * 矩阵变字符串
     * @param chars
     * @return
     */
    public static String joinCharMatrix(char[][] chars) {
        final StringBuilder sb = new StringBuilder();
        for (char[] line: chars) {
            for (int i = 0; i < line.length; i++) {
                char c = line[i];
                if (c == 0) {
                    line[i] = ' ';
                }
            }
            sb.append(line).append("\n");
        }
        return sb.toString();
    }

    /**
     * 画连接线
     * @param prevLine 上一行
     * @param leftChild 是否左子
     * @param parentX 父x坐标
     * @param thisX 自己的x坐标
     */
    public static void drawLine(char[] prevLine, boolean leftChild, int parentX, int thisX) {
        if (leftChild) {
            prevLine[thisX] = '┌';
            if (prevLine[parentX] == '└') {
                prevLine[parentX] = '┴';
            }else {
                prevLine[parentX] = '┘';
            }
            // 到parent之间的画一条线
            drawLine(prevLine, parentX, thisX);
        } else {
            //└┴
            prevLine[thisX] = '┐';
            if (prevLine[parentX] == '┘') {
                prevLine[parentX] = '┴';
            } else {
                prevLine[parentX] = '└';
            }
            // 到parent之间的画一条线
            drawLine(prevLine, thisX, parentX);
        }
    }

    /**
     * 画线
     * @param prevLine 上一行
     * @param start 开始
     * @param end 结束
     */
    private static void drawLine(char[] prevLine, int start, int end) {
        for (int i = end + 1; i < start; i++) {
            prevLine[i] = '─';
        }
    }
}
